package org.xteam.kenken;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.swing.JPanel;

import org.xteam.kenken.Group.Wall;

public class KenKenPanel extends JPanel implements MouseListener {

	private static final long serialVersionUID = -3873032586133913450L;

	private int size;
	private Case[][] cases;
	private Set<Case> selected = new HashSet<Case>();
	private List<Group> groups = new ArrayList<Group>();
	
	public KenKenPanel() {
		super();
		setOpaque(true);
		setBackground(Color.WHITE);
		size = 6;
		reset();
	}
	
	public Dimension getPreferredSize() {
		return new Dimension(500, 500);
	}

	public void setGridSize(int newSize) {
		this.size = newSize;
		reset();
		
	}
	
	public void makeGroup(String operation) {
		Group group = new Group(operation, new ArrayList<Case>(selected));
		Iterator<Group> i = groups.iterator();
		while (i.hasNext()) {
			Group g = i.next();
			if (g.remove(selected))
				i.remove();
		}
		groups.add(group);
		selected.clear();
		repaint();
	}
	
	private void reset() {
		cases = new Case[size][size];
		for (int i = 0; i < size; ++i) {
			for (int j = 0; j < size; ++j) {
				cases[i][j] = new Case(i, j);
			}
		}
		selected.clear();
		groups.clear();
		repaint();
	}

	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		Rectangle rect = getBounds();
		int d = Math.min((int)rect.getMaxX(), (int)rect.getMaxY());
		int step = (d-5) / size;
		for (int i = 0; i < size; ++i) {
			for (int j = 0; j < size; ++j) {
				if (selected.contains(cases[i][j])) {
					g.setColor(new Color(0xCC66FF));
					g.fillRect(j*step, i*step, step, step);
				}
				g.setColor(Color.BLACK);
				g.drawRect(j*step, i*step, step, step);
			}
		}
		
		Graphics2D g2d = (Graphics2D) g;
		g2d.setStroke(new BasicStroke(3));
		Font font = new Font("Helvetica", Font.BOLD, step/4);
		g2d.setFont(font);
		FontMetrics fm = g2d.getFontMetrics(font);
		for (Group group : groups) {
			for (Wall w : group.getHorizontalWalls()) {
				g2d.drawLine(w.x*step, w.y*step, (w.x+1)*step, w.y*step);
			}
			for (Wall w : group.getVerticalWalls()) {
				g2d.drawLine(w.x*step, w.y*step, w.x*step, (w.y+1)*step);
			}
			Case head = group.getHead();
			g.drawString(group.getOperation(), head.x()*step+2, head.y()*step+fm.getAscent()+2);
		}
		
	}

	@Override
	public void mouseClicked(MouseEvent event) {
		Rectangle rect = getBounds();
		int d = Math.min((int)rect.getMaxX(), (int)rect.getMaxY());
		int step = (d-5) / size;
		int x = event.getPoint().x / step;
		int y = event.getPoint().y / step;
		if (x >= size || y >= size) {
			return;
		}
		if ((event.getModifiers() & MouseEvent.SHIFT_MASK) == 0) {
			selected.clear();
		}
		selected.add(cases[y][x]);
		repaint();
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		
	}

	
}
